home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 February / CHIPCD_02_2002.iso / Multimedia / Buzz 1.2 / BuzzME126.exe / Dev / Overloader - Misc / recogg.cpp
Encoding:
C/C++ Source or Header  |  2001-11-09  |  13.2 KB  |  424 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <windows.h>
  4. #include "ogg-include/codec.h"
  5. #include "ogg-include/vorbisenc.h"
  6. #include "resource.h"
  7.   
  8. double const PI = 3.14159265358979323846;
  9.  
  10. HINSTANCE dllInstance;
  11.  
  12. #define MAX_BUFFER_LENGTH        256            // in number of samples
  13.  
  14. class COOERecorder {
  15. public:
  16.     virtual bool __cdecl Init();
  17.  
  18.     virtual bool __cdecl IsMultiTrack();
  19.     virtual bool __cdecl IsTagged();
  20.     virtual bool __cdecl IsStreamed();
  21.     virtual bool __cdecl IsRequiresWaveout();
  22.     virtual bool __cdecl IsLossyCompression();
  23.  
  24.     virtual bool __cdecl IsSampleRateChangeable();
  25.     virtual bool __cdecl SampleRateChanged(int samplerate);
  26.     virtual bool __cdecl IsBitRateChangeable();
  27.     virtual bool __cdecl BitRateChanged(int bitrate);
  28.  
  29.     virtual bool __cdecl SupportsSampleRate(int samplerate);
  30.     virtual bool __cdecl SupportsBitRate(int bitrate);
  31.  
  32.     virtual bool __cdecl SaveAs(HWND parentwindow);
  33.     virtual bool __cdecl ReadyToRec();
  34.  
  35.     virtual bool __cdecl TrackNames(int track_id, char *track_name);
  36.     virtual bool __cdecl SongTagData(int tag_index, char *tagdata);
  37.  
  38.     virtual bool __cdecl Start(char * filename, int samplespersec);
  39.     virtual bool __cdecl WorkOutput(float *psamples, int numsamples);
  40.     virtual bool __cdecl WorkOutputMulti(int track_id, float *psamples, int numsamples);
  41.  
  42.     virtual bool __cdecl Finish();
  43.     virtual void __cdecl ConfigDlg(HWND parentwindow);
  44.     virtual void __cdecl DispatchCommand(int command_id, int param1, int param2, int param3, int param4);
  45.     virtual void __cdecl DispatchCommandEx(char * str_command, char * str_value);
  46.  
  47.     virtual void __cdecl LoadSettings(char * settingsname, char *username, char *domain);
  48.     virtual void __cdecl SaveSettings(char * settingsname, char *username, char *domain);
  49.  
  50.     virtual char * __cdecl OutputFilename();
  51.     virtual char * __cdecl OutputSize();
  52.     virtual char * __cdecl ExtraInfo(int extra_info_id);
  53.     virtual char * __cdecl RecordersWebSiteURL();
  54.  
  55.     virtual int __cdecl RecorderVersion();
  56.  
  57.     virtual void GetRecorderExtensionsClass(int param, void **exmodule);
  58. };
  59.  
  60. class rec : public COOERecorder {
  61. public:
  62.     virtual bool __cdecl Init();
  63.  
  64.     virtual bool __cdecl IsMultiTrack() { return false; };
  65.     virtual bool __cdecl IsTagged() { return true; };
  66.     virtual bool __cdecl IsStreamed() { return false; };
  67.     virtual bool __cdecl IsRequiresWaveout() { return false; };
  68.     virtual bool __cdecl IsLossyCompression() { return false; };
  69.  
  70.     virtual bool __cdecl IsSampleRateChangeable() { return false; };
  71.     virtual bool __cdecl SampleRateChanged(int samplerate) { return false; };
  72.     virtual bool __cdecl IsBitRateChangeable() { return false; };
  73.     virtual bool __cdecl BitRateChanged(int bitrate) { return false; };
  74.  
  75.     virtual bool __cdecl SupportsSampleRate(int samplerate) { return true; };
  76.     virtual bool __cdecl SupportsBitRate(int bitrate) { return true; };
  77.  
  78.     virtual bool __cdecl SaveAs(HWND parentwindow);
  79.     virtual bool __cdecl ReadyToRec();
  80.  
  81.     virtual bool __cdecl TrackNames(int track_id, char *track_name) { return true; };
  82.     virtual bool __cdecl SongTagData(int tag_index, char *tagdata);
  83.  
  84.     virtual bool __cdecl Start(char * filename, int samplespersec);
  85.     virtual bool __cdecl WorkOutput(float *psamples, int numsamples);
  86.     virtual bool __cdecl WorkOutputMulti(int track_id, float *psamples, int numsamples) { return false; };
  87.  
  88.     virtual bool __cdecl Finish();
  89.     virtual void __cdecl ConfigDlg(HWND parentwindow);
  90.     virtual void __cdecl DispatchCommand(int command_id, int param1, int param2, int param3, int param4) { };
  91.     virtual void __cdecl DispatchCommandEx(char * str_command, char * str_value) { };
  92.  
  93.     virtual void __cdecl LoadSettings(char * settingsname, char *username, char *domain) { };
  94.     virtual void __cdecl SaveSettings(char * settingsname, char *username, char *domain) { };
  95.  
  96.     virtual char * __cdecl OutputFilename();
  97.     virtual char * __cdecl OutputSize();
  98.     virtual char * __cdecl ExtraInfo(int extra_info_id) { return "No Extra Info"; };
  99.     virtual char * __cdecl RecordersWebSiteURL() { return "http://www.buzzscene.ca/"; };
  100.  
  101.     virtual int __cdecl RecorderVersion() { return 100; };
  102.  
  103.     virtual void GetRecorderExtensionsClass(int param, void **exmodule) { };
  104. public:
  105.     char myfilename[255];
  106.     FILE * myfilehandle;
  107.     unsigned int writtensofar;
  108.     int bitdepth;
  109.  
  110.     char song_title[255];
  111.     char song_artist[255];
  112.     char song_name[255];
  113.     char song_genre[255];
  114.     char song_keywords[255];
  115.     char song_comments[255];
  116.     char song_copyright[255];
  117.     char song_year[255];
  118.     char song_softpak[255];
  119.  
  120.     vorbis_comment   vc;
  121.     vorbis_dsp_state vd;
  122.     vorbis_block     vb;
  123.     vorbis_info      vi;
  124.     ogg_stream_state os;
  125.     ogg_page         og;
  126.     ogg_packet       op;
  127.     FILE *           flout;
  128.     long             samplesdone;
  129.     int              eos;
  130.     long             bytes_written, packetsdone;
  131.     double           time_elapsed;
  132.     int              ret;
  133. //    TIMER *          timer;
  134.     int              kbps_setting;
  135.     int              bitratebuf;
  136.     int              selbit;
  137.  
  138. };
  139.  
  140. bool rec::Init(){
  141.     sprintf(myfilename, "");
  142.     myfilehandle = NULL;
  143.     writtensofar = 0;
  144.     bitdepth = 0;
  145.     selbit = 2;
  146.     return true;
  147. }
  148. bool rec::SaveAs(HWND parentwindow){
  149.     OPENFILENAME ofl;
  150.     char filename[255];
  151.     int nSuccess;
  152.  
  153.     sprintf(filename,"Untitled.ogg");
  154.     ofl.lStructSize = sizeof(ofl);
  155.     ofl.hwndOwner = parentwindow;
  156.     ofl.hInstance = dllInstance;
  157.     ofl.lpstrFilter = "Ogg Vorbis File (*.ogg)\0*.ogg\0";
  158.     ofl.lpstrCustomFilter = NULL;
  159.     ofl.nMaxCustFilter = NULL;
  160.     ofl.nFilterIndex = 1;
  161.     ofl.lpstrFile = filename;
  162.     ofl.nMaxFile = 255;
  163.     ofl.lpstrFileTitle = NULL;
  164.     ofl.nMaxFileTitle = NULL;
  165.     ofl.lpstrInitialDir = NULL;
  166.     ofl.lpstrTitle = "Save Song Output as";
  167.     ofl.Flags = OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST;
  168.     ofl.nFileOffset = 0;
  169.     ofl.nFileExtension = 0;
  170.     ofl.lpstrDefExt = ".ogg";
  171.     ofl.lCustData = NULL;
  172.     ofl.lpfnHook = NULL;
  173.     ofl.lpTemplateName = NULL;
  174.     nSuccess = GetSaveFileName(&ofl);
  175.     if (nSuccess == 0) {
  176.         sprintf(myfilename, "");
  177. //        SetWindowText(GetDlgItem(hDlg, IDC_FILENAMEBTN), "Save As...");
  178.     } else {
  179.         sprintf(myfilename, ofl.lpstrFile);
  180. //        SetWindowText(GetDlgItem(hDlg, IDC_FILENAMEBTN), ext_hdfilename);
  181.     }
  182.     return true;
  183. }
  184. char *rec::OutputFilename() {
  185.     return myfilename;
  186. }
  187. bool rec::Start (char * filename, int samplespersec) {
  188.     samplesdone = 0;
  189.     bytes_written = 0;
  190.     packetsdone = 0;
  191.     ret = 0;
  192.     switch (selbit) {
  193.     case 0: kbps_setting = 64; break;
  194.     case 1: kbps_setting = 80; break;
  195.     case 2: kbps_setting = 96; break;
  196.     case 3: kbps_setting = 128; break;
  197.     case 4: kbps_setting = 160; break;
  198.     case 5: kbps_setting = 192; break;
  199.     case 6: kbps_setting = 256; break;
  200.     case 7: kbps_setting = 350; break;
  201.     default: kbps_setting = 96;
  202.     }
  203.  
  204.     vorbis_comment_init(&vc);
  205.     flout = fopen(filename, "wb");
  206.     bitratebuf = kbps_setting;
  207.  
  208. //    timer = timer_start();
  209.  
  210.     vorbis_info_init(&vi);
  211.     vorbis_encode_init(&vi, 2, 44100, -1, bitratebuf*1000, -1);
  212.     vorbis_analysis_init(&vd,&vi);
  213.     vorbis_block_init(&vd,&vb);
  214.     ogg_stream_init(&os, 882940);
  215.  
  216.     {
  217.         ogg_packet header_main;
  218.         ogg_packet header_comments;
  219.         ogg_packet header_codebooks;
  220.         int result;
  221.         vorbis_analysis_headerout(&vd,&vc, &header_main,&header_comments,&header_codebooks);
  222.         ogg_stream_packetin(&os,&header_main);
  223.         ogg_stream_packetin(&os,&header_comments);
  224.         ogg_stream_packetin(&os,&header_codebooks);
  225.         while((result = ogg_stream_flush(&os, &og)))
  226.         {
  227.             if(!result) break;
  228.             ret = fwrite(og.header,1,og.header_len, flout);
  229.             ret += fwrite(og.body,1,og.body_len, flout);
  230.             if(!ret) {
  231.                 MessageBox(NULL, "Failed writing header to output stream\n", "OggVorbis Encoder", MB_OK);
  232.                 ret = 1;
  233.                 vorbis_block_clear(&vb);
  234.                 vorbis_dsp_clear(&vd);
  235.                 vorbis_info_clear(&vi);
  236.                 fflush(flout);
  237.                 fclose(flout);
  238.             } else bytes_written += ret;
  239.         }
  240.     }
  241.  
  242.     eos = 0;
  243.  
  244.     writtensofar = 0;
  245.  
  246.     return true;
  247. }
  248.  
  249. bool rec::ReadyToRec() {
  250.     if (strcmp(myfilename, "") == 0) {
  251.         return false;
  252.     } else {
  253.         return true;
  254.     }
  255. }
  256.  
  257. bool rec::SongTagData(int tag_index, char *tagdata) {
  258.     if (strlen(tagdata) > 250) tagdata[250] = 0;
  259.     switch (tag_index) {
  260.     case 0: sprintf(song_title, tagdata);    return true; break;
  261.     case 1: sprintf(song_artist, tagdata);   return true; break;
  262.     case 2: sprintf(song_name, tagdata);    return true; break;
  263.     case 3: sprintf(song_genre, tagdata);    return true; break;
  264.     case 4: sprintf(song_keywords, tagdata); return true; break;
  265.     case 5: sprintf(song_comments, tagdata); return true; break;
  266.     case 9: sprintf(song_copyright, tagdata);return true; break;
  267.     case 10: sprintf(song_year, tagdata);    return true; break;
  268.     case 13: sprintf(song_softpak, tagdata); return true; break;
  269.     default: return false; break;
  270.     }
  271. }
  272.  
  273. bool rec::WorkOutput (float *psamples, int numsamples) {
  274.     int i_rn;
  275.     int i_rx = 0;
  276.     float **buffer = vorbis_analysis_buffer(&vd, numsamples);
  277.     for (i_rn = 0; i_rn < (numsamples*2); i_rn++) {
  278.         buffer[0][i_rx] = psamples[i_rn] / 32768.0f;
  279.         i_rn++;
  280.         buffer[1][i_rx] = psamples[i_rn] / 32768.0f;
  281.         i_rx++;
  282.     }
  283.     if(numsamples ==0) {
  284.         vorbis_analysis_wrote(&vd,0);
  285.     } else {
  286.         samplesdone += numsamples*2;
  287.         vorbis_analysis_wrote(&vd, numsamples);
  288.     }
  289.     while(vorbis_analysis_blockout(&vd,&vb)==1) {
  290.         vorbis_analysis(&vb, &op);
  291.         ogg_stream_packetin(&os,&op);
  292.         packetsdone++;
  293.         while(!eos) {
  294.             int result = ogg_stream_pageout(&os,&og);
  295.             if(!result) break;
  296.             ret = fwrite(og.header,1,og.header_len, flout);
  297.             ret += fwrite(og.body,1,og.body_len, flout);
  298.             if(!ret)
  299.             {
  300.                 MessageBox(NULL, "Failed writing data to output stream\n", "OggVorbis Encoder", MB_OK);
  301.                 ret = 1;
  302.                 ogg_stream_clear(&os);
  303.                 vorbis_block_clear(&vb);
  304.                 vorbis_dsp_clear(&vd);
  305.                 vorbis_info_clear(&vi);
  306.                 fflush(flout);
  307.                 fclose(flout);
  308.             } else bytes_written += ret; 
  309.             if(ogg_page_eos(&og)) eos = 1;
  310.         }
  311.     }
  312.  
  313.     return true;
  314. }
  315.  
  316. bool rec::Finish() {
  317.     vorbis_block_clear(&vb);
  318.     vorbis_dsp_clear(&vd);
  319.     vorbis_info_clear(&vi);
  320.     fflush(flout);
  321.     fclose(flout);
  322.     return true;
  323. }
  324.  
  325. char * rec::OutputSize() {
  326.     static char megs[32];
  327.     switch (bitdepth) {
  328.     case 0:
  329.         sprintf(megs, "%.2fM", ((float)writtensofar * 4.0f / 1024.0f / 1024.0f));
  330.         break;
  331.     case 1:
  332.         sprintf(megs, "%.2fM", ((float)writtensofar * 6.0f / 1024.0f / 1024.0f));
  333.         break;
  334.     case 2:
  335.         sprintf(megs, "%.2fM", ((float)writtensofar * 2.0f * (float)sizeof(float) / 1024.0f / 1024.0f));
  336.         break;
  337.     case 3:
  338.         sprintf(megs, "%.2fM", ((float)writtensofar * 2.0f * (float)sizeof(int) / 1024.0f / 1024.0f));
  339.         break;
  340.     default:
  341.         sprintf(megs, "%.2fM", ((float)writtensofar * 4.0f / 1024.0f / 1024.0f));
  342.         break;
  343.     }
  344.     return megs;
  345. }
  346.  
  347. rec *prec;
  348.  
  349. BOOL APIENTRY ConfigDialog (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  350.     switch(uMsg) {
  351.     case WM_INITDIALOG:
  352.     {
  353.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_RESETCONTENT, 0, 0);
  354.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("64 kbps Stereo"));
  355.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("80 kbps Stereo"));
  356.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("96 kbps Stereo"));
  357.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("128 kbps Stereo"));
  358.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("160 kbps Stereo"));
  359.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("192 kbps Stereo"));
  360.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("256 kbps Stereo"));
  361.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_ADDSTRING,0,(LPARAM)(LPCTSTR)("350 kbps Stereo"));
  362.         SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_SETCURSEL, (int)(prec->selbit), 0);
  363.  
  364.         return 1;
  365.     }
  366.     case WM_SHOWWINDOW:
  367.     {
  368.         return 1;
  369.     }
  370.     case WM_CLOSE:
  371.     {
  372.         EndDialog (hDlg, TRUE);
  373.     }
  374.     case WM_COMMAND:
  375.         switch ( LOWORD (wParam))
  376.         {
  377.         case IDOK:
  378.             prec->selbit = (int)SendMessage(GetDlgItem(hDlg, IDC_QCOMBO), CB_GETCURSEL, 0, 0);
  379.             switch (prec->selbit) {
  380.             case 0: prec->kbps_setting = 64; break;
  381.             case 1: prec->kbps_setting = 80; break;
  382.             case 2: prec->kbps_setting = 96; break;
  383.             case 3: prec->kbps_setting = 128; break;
  384.             case 4: prec->kbps_setting = 160; break;
  385.             case 5: prec->kbps_setting = 192; break;
  386.             case 6: prec->kbps_setting = 256; break;
  387.             case 7: prec->kbps_setting = 350; break;
  388.             default: prec->kbps_setting = 96;
  389.             }
  390.             
  391.             EndDialog (hDlg, TRUE);
  392.             break;
  393.         case IDCANCEL:
  394.             EndDialog (hDlg, TRUE);
  395.             break;
  396.         default:
  397.             return 0;
  398.         }
  399.         break;
  400.     }
  401.     return 0;
  402. }
  403.  
  404. void rec::ConfigDlg (HWND parentwindow) {
  405.     prec = this;
  406.     DialogBox(dllInstance, MAKEINTRESOURCE (IDD_CONFIG), parentwindow, (DLGPROC) &ConfigDialog);
  407. }
  408.  
  409. extern "C" {
  410. __declspec(dllexport) COOERecorder * __cdecl CreateRecorder() { return new rec; }
  411. __declspec(dllexport) char * __cdecl RecInfo() { return "Ogg Vorbis Recorder by CyanPhase"; }
  412. }
  413.  
  414. BOOL WINAPI DllMain ( HANDLE hModule, DWORD fwdreason, LPVOID lpReserved )
  415. {
  416.     switch (fwdreason) {
  417.     case DLL_PROCESS_ATTACH: { dllInstance = (HINSTANCE) hModule; } break;
  418.     case DLL_THREAD_ATTACH: break;
  419.     case DLL_THREAD_DETACH: break;
  420.     case DLL_PROCESS_DETACH: break;
  421.     }
  422.     return TRUE;
  423. }
  424.